﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace OpSatPlan.SatSolvers
{
    public class SolverFactory
    {
        private static SolverFactory mFactory;
        private Dictionary<string, SatSolver> mSolvers;

        public static SolverFactory Instance
        {
            get
            {
                if (SolverFactory.mFactory == null)
                {
                    SolverFactory.mFactory = new SolverFactory();
                }
                return SolverFactory.mFactory;
            }
        }

        private SolverFactory()
        {
            this.mSolvers = new Dictionary<string, SatSolver>();
            this.Initialize();
        }

        private void Initialize()
        {
            Assembly asm = Assembly.GetCallingAssembly();
            Type[] allTypes;
            Type iSolver;
            Type solver;

            allTypes = asm.GetTypes();
            iSolver = asm.GetType("OpSatPlan.SatSolvers.SatSolver");

            foreach (Type t in allTypes)
            {
                if (t.IsClass && !t.IsAbstract && t.IsSubclassOf(iSolver))
                {
                    solver = t;
                    if (solver != null)
                    {
                        Object obj = asm.CreateInstance(t.FullName, true, BindingFlags.CreateInstance, null, null, null, null);
                        if (obj != null)
                        {
                            SatSolver s = (SatSolver)obj;
                            this.mSolvers.Add(s.Name, s);
                        }
                    }
                }
            }
        }

        public SatSolver GetSolver(string name)
        {
            return this.mSolvers[name];
        }
    }
}
